package com.xiaochong.tir.apiservice.service;

import com.alibaba.fastjson.JSON;
import com.xc.logclient.utils.LogTrace;
import com.xiaochong.tir.apiservice.component.CoinMarketCapDataComponent;
import com.xiaochong.tir.apiservice.component.HbaseBaseQueryComponent;
import com.xiaochong.tir.apiservice.component.hbase.CurrencyInfoHbaseComponent;
import com.xiaochong.service.common.config.redis.RedisServer;
import com.xiaochong.tir.common.data.hbasepo.CmcCurrencyInfo;
import com.xiaochong.tir.common.data.hbasepo.DailyComprehensiveAnalysisInfo;
import com.xiaochong.tir.common.data.hbasepo.KLineCmcData;
import com.xiaochong.tir.common.data.mapper.CurrencyInfoHbaseMapper;
import com.xiaochong.tir.common.data.po.CurrencyInfoHbase;
import com.xiaochong.tir.common.exception.hbase.HbaseCloseExcetion;
import com.xiaochong.tir.common.exception.hbase.HbaseConnectionExcetion;
import com.xiaochong.tir.common.exception.hbase.HbaseGetTableExcetion;
import com.xiaochong.tir.common.util.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * @Project : xc-tir
 * @Package Name : com.xiaochong.tir.apiservice.service
 * @Description : TODO Cmc数据处理服务
 * @Author : daizhiqing@xiaochong.com
 * @Creation Date : 2018年07月10日下午5:54
 * @ModificationHistory Who When What
 */
@Service
public class CmcDataDealService {

    @Autowired
    private HbaseBaseQueryComponent hbaseBaseQueryComponent;

    @Autowired
    private CurrencyInfoHbaseComponent currencyInfoHbaseComponent;

    @Autowired
    private CurrencyInfoHbaseMapper currencyInfoHbaseMapper;

    @Autowired
    RedisServer redisServer;

    @Autowired
    private CoinMarketCapDataComponent coinMarketCapDataComponent;

    /**
     * 获取Cmc数据的K线Ma均线
     * @param cmcId
     * @param days
     */
    public BigDecimal getCmcMaData(String cmcId , int days){
        //获取当前的日期时间
        LocalDateTime dateTime = LocalDateTime.now();

        BigDecimal totalPrice  = new BigDecimal(0);

        for (int i = 1; i <= days; i++) {
            //获取计算的时间
            LocalDateTime dateCalculate = dateTime.minusDays(i);

            String rowKey = cmcId + DateUtils.localDateTimeFormatString( dateCalculate , DateUtils.format_ymds);

            LogTrace.info("getCmcMaData", "rowKey",rowKey);
            try {
                Map<String,Object> map = hbaseBaseQueryComponent.selectData(HbaseTableUtils.CURRENCY_INFO_K_LINE_TABLE_NAME ,rowKey);
                //某一天日K线
                KLineCmcData kLineCmcDay = JSON.parseObject(JSON.toJSONString(map), KLineCmcData.class);

                if(map.size() >0 && kLineCmcDay!= null){
                    totalPrice = totalPrice.add(new BigDecimal(kLineCmcDay.getOpenPrice()));
                }

            } catch (HbaseConnectionExcetion hbaseConnectionExcetion) {
                hbaseConnectionExcetion.printStackTrace();
            } catch (HbaseGetTableExcetion hbaseGetTableExcetion) {
                hbaseGetTableExcetion.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (HbaseCloseExcetion hbaseCloseExcetion) {
                hbaseCloseExcetion.printStackTrace();
            }
        }
        BigDecimal value =  totalPrice.divide(new BigDecimal(days),5,BigDecimal.ROUND_DOWN);
        LogTrace.infoKvs("获取Cmc数据"+days+"Ma均线",
                "cmcId",cmcId,
                "totalPrice", totalPrice+"",
                "MaValue" , value.toString());
        return value;
    }

    /**
     * 生成小时数据的K线 CMC
     * @param nowDate
     */
//    public void cmcKdataHours(LocalDateTime  nowDate ,  String cmc_id){
//
//        if(StringUtils.isBlank(cmc_id)){
//            return;
//        }
//        //rowKey规则
//
//        String dateStr = DateUtils.localDateTimeFormatString(nowDate.minusHours(1) , DateUtils.format_ymdh);
//        String rowKey = cmc_id + dateStr;
//
//        //查询当前CMCID的一小时数据
//        List<CurrencyInfoHbase> currencyInfoHbaseList = currencyInfoHbaseMapper.listOneHours(cmc_id , dateStr);
//
//        LogTrace.info("currencyInfoHbaseList","currencyInfoHbaseList" ,rowKey + "一小时数据量"+(currencyInfoHbaseList != null ? currencyInfoHbaseList.size() : 0) );
//        if(currencyInfoHbaseList != null && currencyInfoHbaseList.size()>0){
//            KLineCmcData kLineCmcData = new KLineCmcData();
//            kLineCmcData.setCmcId(cmc_id);
//            kLineCmcData.setDateTime(DateUtils.localDateTimeToDate(nowDate.minusHours(1)).getTime()+"");
//
//            for (CurrencyInfoHbase currencyInfoHbase : currencyInfoHbaseList) {
//                try {
//                    //获取1小时的rowKey
//                    Map<String , Object> currencyInfoMap =  hbaseBaseQueryComponent.selectData(HbaseTableUtils.CURRENCY_INFO_TABLE_NAME , currencyInfoHbase.getRowKey());
//
//                    if(currencyInfoMap == null || currencyInfoMap.size() <= 0){
//                        continue;
//                    }
//                    CmcCurrencyInfo cmcCurrencyInfo = JSON.parseObject(JSON.toJSONString(currencyInfoMap), CmcCurrencyInfo.class);
//                    //开盘价格
//                    if(StringUtils.isBlank(kLineCmcData.getOpenPrice())){
//                        kLineCmcData.setOpenPrice(cmcCurrencyInfo.getPriceCny());
//                    }
//                    //收盘价
//                    kLineCmcData.setClosePrice(cmcCurrencyInfo.getPriceCny());
//
//                    if(StringUtils.isBlank(kLineCmcData.getHighestPrice()) || new BigDecimal(kLineCmcData.getHighestPrice()).compareTo(new BigDecimal(cmcCurrencyInfo.getPriceCny()))<0){
//                        kLineCmcData.setHighestPrice(cmcCurrencyInfo.getPriceCny());
//                    }
//
//                    if(StringUtils.isBlank(kLineCmcData.getLowestPrice()) || new BigDecimal(kLineCmcData.getLowestPrice()).compareTo(new BigDecimal(cmcCurrencyInfo.getPriceCny()))>0){
//                        kLineCmcData.setLowestPrice(cmcCurrencyInfo.getPriceCny());
//                    }
//                    kLineCmcData.setVolume(new BigDecimal(cmcCurrencyInfo.getVolume24hCny()).divide(new BigDecimal(cmcCurrencyInfo.getPriceCny()), 8 , BigDecimal.ROUND_HALF_EVEN).toString());
//
//                } catch (HbaseConnectionExcetion hbaseConnectionExcetion) {
//                    hbaseConnectionExcetion.printStackTrace();
//                } catch (HbaseGetTableExcetion hbaseGetTableExcetion) {
//                    hbaseGetTableExcetion.printStackTrace();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                } catch (HbaseCloseExcetion hbaseCloseExcetion) {
//                    hbaseCloseExcetion.printStackTrace();
//                }
//
//            }
//            LogTrace.info("cmcKdataHours生成CMC小时K线","rowKey",rowKey);
//            currencyInfoHbaseComponent.insertHbaseObject(HbaseTableUtils.CURRENCY_INFO_K_LINE_TABLE_NAME ,rowKey, HbaseTableUtils.CURRENCY_INFO_K_LINE_TABLE_FAMILY , kLineCmcData);
//        }
//
//        //计算日K
//        if(nowDate.getHour() == 0){
//            LocalDateTime yestoday = nowDate.minusDays(1);
//            //昨天的日K线
//            String rowKeyDay = cmc_id + DateUtils.localDateTimeFormatString( yestoday , DateUtils.format_ymds);
//
//            //CMC 日K数据
//            KLineCmcData kLineCmcDay = null;
//
//            while (nowDate.compareTo(yestoday)>0){
//                String hoursRowKey = cmc_id+DateUtils.localDateTimeFormatString(yestoday , DateUtils.format_ymdh);
//                try {
//                    Map<String , Object> currencyInfoKlineHours  = hbaseBaseQueryComponent.selectData(HbaseTableUtils.CURRENCY_INFO_K_LINE_TABLE_NAME , hoursRowKey);
//                    //货币一小时的K线
//                    KLineCmcData kLineCmcData = JSON.parseObject(JSON.toJSONString(currencyInfoKlineHours), KLineCmcData.class);
//                    if(currencyInfoKlineHours.size()>0 && kLineCmcData != null){
//                        if(null == kLineCmcDay){
//                            kLineCmcDay  = new KLineCmcData();
//                            kLineCmcDay.setCmcId(cmc_id);
//                            kLineCmcDay.setDateTime(DateUtils.localDateTimeToDate(yestoday).getTime()+"");
//                        }
//                        //TODO:
//                        if(StringUtils.isBlank(kLineCmcDay.getOpenPrice())){
//                            kLineCmcDay.setOpenPrice(kLineCmcData.getOpenPrice());
//                        }
//
//                        if(StringUtils.isBlank(kLineCmcDay.getHighestPrice()) ||
//                                new BigDecimal(kLineCmcDay.getHighestPrice()).compareTo(new BigDecimal(kLineCmcData.getOpenPrice()))<0){
//                            kLineCmcDay.setHighestPrice(kLineCmcData.getOpenPrice());
//                        }
//
//                        if(StringUtils.isBlank(kLineCmcDay.getLowestPrice()) ||
//                                new BigDecimal(kLineCmcDay.getLowestPrice()).compareTo(new BigDecimal(kLineCmcData.getLowestPrice()))>0){
//                            kLineCmcDay.setLowestPrice(kLineCmcData.getLowestPrice());
//                        }
//
//                        if(StringUtils.isBlank(kLineCmcDay.getClosePrice())){
//                            kLineCmcDay.setClosePrice(kLineCmcData.getClosePrice());
//                        }
//
//                        kLineCmcDay.setVolume(kLineCmcData.getVolume());
//                    }
//
//                } catch (HbaseConnectionExcetion hbaseConnectionExcetion) {
//                    hbaseConnectionExcetion.printStackTrace();
//                } catch (HbaseGetTableExcetion hbaseGetTableExcetion) {
//                    hbaseGetTableExcetion.printStackTrace();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                } catch (HbaseCloseExcetion hbaseCloseExcetion) {
//                    hbaseCloseExcetion.printStackTrace();
//                }finally {
//                    yestoday =  yestoday.plusHours(1);
//                }
//            }
//            if(kLineCmcDay != null){
//                LogTrace.info("cmcKdataHours生成CMC日K线","rowKeyDay",rowKeyDay);
//                currencyInfoHbaseComponent.insertHbaseObject(HbaseTableUtils.CURRENCY_INFO_K_LINE_TABLE_NAME ,rowKeyDay, HbaseTableUtils.CURRENCY_INFO_K_LINE_TABLE_FAMILY , kLineCmcDay);
//            }
//
//        }
//    }

    /**
     * 计算24小时最高价最低价
     * @param dateDate
     * @param cmcId
     */
    public void calueCmcPriceHighLowScheduled(LocalDateTime dateDate, String cmcId) {


        //查询当前CMCID的一小时数据
        List<CurrencyInfoHbase> currencyInfoHbaseList = currencyInfoHbaseMapper.listAfterCreateTime(cmcId , DateUtils.localDateTimeToDate(dateDate.minusHours(24)));

        LogTrace.info("calueCmcPriceHighLowScheduled" ,cmcId+ "24小时数据量"  ,  ""+currencyInfoHbaseList.size());

        String highPriceKey =  RedisKeysUtils.TIR_CMC_HIGH_PRICE+cmcId;
        String lowPriceKey =  RedisKeysUtils.TIR_CMC_LOW_PRICE+cmcId;

        String highPrice = "0";
        String lowPrice = "0";

        redisServer.remove(highPriceKey);
        redisServer.remove(lowPriceKey);
        for (CurrencyInfoHbase currencyInfoHbase : currencyInfoHbaseList) {
            //获取1小时的rowKey
            Map<String , Object> currencyInfoMap = null;
            try {
                currencyInfoMap = hbaseBaseQueryComponent.selectData(HbaseTableUtils.CURRENCY_INFO_TABLE_NAME , currencyInfoHbase.getRowKey());
                if(currencyInfoMap == null || currencyInfoMap.size() <= 0){
                    continue;
                }
                CmcCurrencyInfo cmcCurrencyInfo = JSON.parseObject(JSON.toJSONString(currencyInfoMap), CmcCurrencyInfo.class);

                String priceCny =cmcCurrencyInfo.getPriceCny();

                if(new BigDecimal(highPrice).compareTo(new BigDecimal(priceCny))< 0 ){
                    highPrice = priceCny;
                }

                if("0".equals(lowPrice) || new BigDecimal(lowPrice).compareTo(new BigDecimal(priceCny)) > 0){
                    lowPrice = priceCny;
                }
            } catch (HbaseConnectionExcetion hbaseConnectionExcetion) {
                hbaseConnectionExcetion.printStackTrace();
            } catch (HbaseGetTableExcetion hbaseGetTableExcetion) {
                hbaseGetTableExcetion.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (HbaseCloseExcetion hbaseCloseExcetion) {
                hbaseCloseExcetion.printStackTrace();
            }
        }
        if(new BigDecimal(highPrice).compareTo(new BigDecimal(1))>=0){
           //保留两位小数
            highPrice = new BigDecimal(highPrice).setScale(2 ,BigDecimal.ROUND_HALF_UP).toString();
        }else{
            highPrice = MathUtils.roundToSignificantFigures(new BigDecimal(highPrice).doubleValue() , 5);
        }
        if(new BigDecimal(lowPrice).compareTo(new BigDecimal(1))>=0){
            //保留两位小数
            lowPrice = new BigDecimal(lowPrice).setScale(2 ,BigDecimal.ROUND_HALF_UP).toString();
        }else{
            lowPrice = MathUtils.roundToSignificantFigures(new BigDecimal(lowPrice).doubleValue() , 5);
        }


        redisServer.set(highPriceKey , highPrice);
        redisServer.set(lowPriceKey , lowPrice);

    }

    /**
     * 生成CMC日K数据
     * @param nowDate
     * @param cmc_id
     */
    public void cmcKDataDay(LocalDateTime  nowDate ,  String cmc_id){
        if(StringUtils.isBlank(cmc_id)){
            return;
        }

        LocalDateTime calueTime = nowDate.minusDays(1);
        String rowKey =  cmc_id +"@"+ DateUtils.localDateTimeFormatString( calueTime , DateUtils.format_ymds);

        //昨天的日K线
        String rowKeyDay = cmc_id + DateUtils.localDateTimeFormatString( calueTime , DateUtils.format_ymds);

        if(nowDate.getHour() == 0){
            Map<String, List<DailyComprehensiveAnalysisInfo>> dailyMap =
                    coinMarketCapDataComponent.getDailyCurrencyInfor(rowKey);

            if(CollectionUtil.isNotBlank(dailyMap)){
                //CMC 日K数据
                KLineCmcData kLineCmcDay = new KLineCmcData();
                kLineCmcDay.setCmcId(cmc_id);
                kLineCmcDay.setDateTime(DateUtils.localDateTimeToDate(calueTime).getTime()+"");

                for (Map.Entry<String, List<DailyComprehensiveAnalysisInfo>> entry : dailyMap.entrySet()){

                    List<DailyComprehensiveAnalysisInfo> list = entry.getValue();
                    if(list == null || list.size() <=0){ continue;}


                    if("0".equals(entry.getKey())){
                        kLineCmcDay.setOpenPrice(entry.getValue().get(0).getPriceCny());
                    }

                    if("23".equals(entry.getKey())){
                        DailyComprehensiveAnalysisInfo dailyComprehensiveAnalysisInfo = entry.getValue().get(list.size()-1);

                        kLineCmcDay.setClosePrice(dailyComprehensiveAnalysisInfo.getPriceCny());
                        if(StringUtils.isBlank(dailyComprehensiveAnalysisInfo.getVolume24hCny())
                                ||
                                StringUtils.isBlank(dailyComprehensiveAnalysisInfo.getPriceCny())){
                            kLineCmcDay.setVolume("0");
                        }else{
                            kLineCmcDay.setVolume(new BigDecimal(dailyComprehensiveAnalysisInfo.getVolume24hCny()).divide(new BigDecimal(dailyComprehensiveAnalysisInfo.getPriceCny()), 8 , BigDecimal.ROUND_HALF_EVEN).toString());
                        }
                    }

                    for ( DailyComprehensiveAnalysisInfo dailyComprehensiveAnalysisInfo : list) {
                        //设置最高价
                        if(StringUtils.isBlank(kLineCmcDay.getHighestPrice()) ||
                                new BigDecimal(kLineCmcDay.getHighestPrice()).compareTo(new BigDecimal(dailyComprehensiveAnalysisInfo.getPriceCny())) < 0){
                            kLineCmcDay.setHighestPrice(dailyComprehensiveAnalysisInfo.getPriceCny());
                        }


                        //设置最低价
                        if(StringUtils.isBlank(kLineCmcDay.getLowestPrice()) ||
                                new BigDecimal(kLineCmcDay.getLowestPrice()).compareTo(new BigDecimal(dailyComprehensiveAnalysisInfo.getPriceCny())) > 0){
                            kLineCmcDay.setLowestPrice(dailyComprehensiveAnalysisInfo.getPriceCny());
                        }
                    }

                }
                LogTrace.info("cmcKDataDay生成CMC日K线","rowKeyDay",rowKeyDay);
                currencyInfoHbaseComponent.insertHbaseObject(HbaseTableUtils.CURRENCY_INFO_K_LINE_TABLE_NAME ,rowKeyDay, HbaseTableUtils.CURRENCY_INFO_K_LINE_TABLE_FAMILY , kLineCmcDay);

            }else{
                LogTrace.info("cmcKDataDayDataIsNull" , "rowKey",rowKey);
            }
        }else{
            LogTrace.infoKvs("cmcKDataDayIsNoTime" , "rowKey",rowKey ,"cmc_id",cmc_id);
        }

    }
}
